<template>
  <el-dialog
    v-model="dialogVisible"
    title="分配菜单权限"
    width="800px"
    :close-on-click-modal="false"
    @close="handleClose"
  >
    <div class="menu-assign-container">
      <div class="role-info mb-4">
        <el-alert :title="`正在为角色「${roleData?.name}」分配菜单权限`" type="info" :closable="false" />
      </div>

      <div class="menu-tree-container">
        <el-tree
          ref="menuTreeRef"
          :data="menuTreeData"
          :props="treeProps"
          show-checkbox
          node-key="id"
          :default-checked-keys="checkedKeys"
          :default-expanded-keys="expandedKeys"
          check-strictly
          class="menu-tree"
        >
          <template #default="{ node, data }">
            <div class="menu-node">
              <el-icon v-if="data.icon" class="menu-icon">
                <component :is="data.icon" />
              </el-icon>
              <span class="menu-name">{{ node.label }}</span>
              <el-tag
                v-if="data.type"
                :type="getMenuTypeTag(data.type)"
                size="small"
                class="menu-type"
              >{{ getMenuTypeName(data.type) }}</el-tag>
            </div>
          </template>
        </el-tree>
      </div>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
        <el-button type="primary" :loading="loading" @click="handleSubmit">确定</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, reactive, watch, computed, nextTick } from "vue";
import { ElMessage } from "element-plus";
import { getMenuTreeByRoleCode, assignMenusToRole } from "@/api/menu";

const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false,
  },
  roleData: {
    type: Object,
    default: null,
  },
});

const emit = defineEmits(["update:modelValue", "success"]);

const menuTreeRef = ref();
const loading = ref(false);
const menuTreeData = ref([]);
const checkedKeys = ref([]);
const expandedKeys = ref([]);

const treeProps = {
  label: "name",
  children: "children",
};

const dialogVisible = computed({
  get: () => props.modelValue,
  set: (val) => emit("update:modelValue", val),
});

// 获取菜单类型标签样式
const getMenuTypeTag = (type) => {
  switch (type) {
    case 1:
      return "";
    case 2:
      return "success";
    case 3:
      return "warning";
    default:
      return "info";
  }
};

// 获取菜单类型名称
const getMenuTypeName = (type) => {
  switch (type) {
    case 1:
      return "目录";
    case 2:
      return "菜单";
    case 3:
      return "按钮";
    default:
      return "未知";
  }
};

// 加载角色菜单数据
const loadRoleMenus = async () => {
  if (!props.roleData) return;

  try {
    loading.value = true;
    const data = await getMenuTreeByRoleCode(props.roleData.code);
    menuTreeData.value = data.menus || [];
    checkedKeys.value = data.checkedKeys || [];
    console.log("🚀 ~ loadRoleMenus ~ data.checkedKeys:", data.checkedKeys);

    // 默认展开所有节点
    const expandAllNodes = (nodes) => {
      const keys = [];
      nodes.forEach((node) => {
        keys.push(node.id);
        if (node.children && node.children.length > 0) {
          keys.push(...expandAllNodes(node.children));
        }
      });
      return keys;
    };

    expandedKeys.value = expandAllNodes(menuTreeData.value);

    // 等待DOM更新后手动设置选中状态
    await nextTick();
    if (menuTreeRef.value && checkedKeys.value.length > 0) {
      menuTreeRef.value.setCheckedKeys(checkedKeys.value);
    }
  } catch (error) {
    ElMessage.error("获取角色菜单数据失败");
  } finally {
    loading.value = false;
  }
};

// 监听对话框打开状态和角色数据变化
watch(
  [() => props.modelValue, () => props.roleData],
  ([newVal, newRoleData], [oldVal, oldRoleData]) => {
    // 当对话框打开且角色数据存在时加载菜单
    if (newVal && newRoleData) {
      // 如果是对话框刚打开或者角色数据发生变化，则重新加载菜单
      if (!oldVal || (oldRoleData && oldRoleData.code !== newRoleData.code)) {
        loadRoleMenus();
      }
    }
  }
);

const handleClose = () => {
  dialogVisible.value = false;
  menuTreeData.value = [];
  checkedKeys.value = [];
  expandedKeys.value = [];
};

const handleSubmit = async () => {
  if (!props.roleData) return;

  try {
    loading.value = true;

    // 获取选中的菜单ID
    const checkedMenuIds = menuTreeRef.value.getCheckedKeys();
    const halfCheckedMenuIds = menuTreeRef.value.getHalfCheckedKeys();
    const allMenuIds = [...checkedMenuIds, ...halfCheckedMenuIds];

    await assignMenusToRole(props.roleData.code, {
      menuIds: allMenuIds,
    });

    ElMessage.success("菜单权限分配成功");
    emit("success");
    handleClose();
  } catch (error) {
    ElMessage.error("菜单权限分配失败");
  } finally {
    loading.value = false;
  }
};
</script>

<style scoped>
.menu-assign-container {
  max-height: 500px;
  overflow-y: auto;
}

.menu-tree-container {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  padding: 10px;
}

.menu-tree {
  min-height: 300px;
}

.menu-node {
  display: flex;
  align-items: center;
  gap: 8px;
}

.menu-icon {
  font-size: 16px;
  color: #909399;
}

.menu-name {
  font-size: 14px;
  color: #303133;
}

.menu-type {
  font-size: 12px;
}

.dialog-footer {
  text-align: right;
}
</style>